import type {HttpResponse} from "luch-request";
import {ApiEncrypt} from "@/utils/encrypt";
import errorCode from "@/utils/errorCode";
import {config} from '@/config/request/config'
import {getRefreshToken, setAccessToken, setRefreshToken, setTokenExpiresTime} from "@/utils/auth";
import {closeLoading} from "@/config/request/reqInter";
import {$user} from "@/store";
import httpRequest from "@/config/request/service";

/**
 * 响应前拦截器
 */
export const resInter = async (response: HttpResponse) => {
    console.log(response.config.url, "收到回调", response.data)

    await encryptHandler(response) // 数据解密
    await tokenHandler(response)

    const code = response.data.code || result_code
    const msg = response.data.msg || errorCode[code] || errorCode['default']

    response.config.custom?.showLoading && closeLoading() // 关闭 loading

    if (code === 401) {
        return await errorCode401Handler(response)
    } else if (code === 500 || code === 1002018000) {
        await uni.showToast({title: msg, icon: "none"})
        isRefreshToken = false
        requestList = []
        return Promise.reject(response.data)
    }

    isRefreshToken = false

    if (
        response.config.custom?.showSuccess &&
        response.config.custom?.successMsg !== '' &&
        response.data.code === result_code
    ) {
        await uni.showToast({
            title: response.config.custom?.successMsg,
            icon: 'none',
        });
    }

    console.log("正常请求返回", response.config.url, response.data)
    return Promise.resolve(response.data);
}


/**
 * 数据解密
 */
async function encryptHandler(response: HttpResponse) {
    const encryptHeader = ApiEncrypt.getEncryptHeader()
    const isEncryptResponse =
        response.header[encryptHeader] === 'true' ||
        response.header[encryptHeader.toLowerCase()] === 'true'
    if (isEncryptResponse && typeof response.data === 'string') {
        try {
            response.data = ApiEncrypt.decryptResponse(response.data)
        } catch (error) {
            console.error('响应数据解密失败:', error)
            throw new Error('响应数据解密失败: ' + (error as Error).message)
        }
    }
}

let isRefreshToken = false
let requestList: any[] = []; // 请求队列
const {result_code} = config

/**
 * 处理 401 登录异常
 */
async function errorCode401Handler(response: HttpResponse): Promise<any> {
    console.log(response.config.url, "401 token 异常处理")
    if (!isRefreshToken) {
        isRefreshToken = true
        console.log(response.config.url, "进入自动刷新流程")
        if (!getRefreshToken()) {
            console.log(response.config.url, "没有缓存 Token 重新登录")
            let {code} = await $user.login()
            //  用户注册，跳转登录注册页面
            if (code === 1004001000) {
                console.debug(response.config.url, "用户未注册，跳转注册登录页")
                requestList = []
                isRefreshToken = false
                await uni.reLaunch({url: '/pages/login/index'})
                return Promise.resolve(response)
            }
            console.log(response.config.url, "登录完成，重新请求返回")
            requestList.forEach(cb => cb());
            requestList = []
            return httpRequest(response.config)
        } else {
            try {
                console.log(response.config.url, "存在 token 自动刷新")
                await $user.refreshToken()
                // 刷新成功重新执行后面发送的请求
                requestList.forEach(cb => cb());
                requestList = []
                return httpRequest(response.config)
            } catch (error) {
                console.error(error)
                // 遇到异常，跳转登录界面
                await gotoLogin()
            } finally {
                // 执行完成恢复刷新设置为初始状态
                requestList = [];
                isRefreshToken = false;
            }
        }
    } else {
        console.log(response.config.url, "放入队列，等待执行", requestList)
        // 添加到队列，等待刷新获取到新的令牌
        return new Promise((resolve) => {
            requestList.push(() => {
                resolve(httpRequest(response.config));
            });
        });
    }
}

/**
 * Token 自动处理
 */
async function tokenHandler(response: HttpResponse) {
    if (response.config.url?.indexOf("login") == -1 &&
        response.config.url?.indexOf("token") == -1) return
    if (!response.data!.data?.accessToken) return
    console.debug(response.config.url, "识别到 token 请求接口，自动保存 token")
    setAccessToken(response.data.data!.accessToken)
    setRefreshToken(response.data.data!.refreshToken || '')
    setTokenExpiresTime(response.data.data!.expiresTime || 0)
}

/**
 * 跳转登录界面
 */
async function gotoLogin() {
    await uni.navigateTo({url: "/pages/login/index"});
}
